package com.musichord.core.sequence;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Vector;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Track;

import com.musichord.core.message.InstrumentMessage;
import com.musichord.core.message.MeterMessage;
import com.musichord.core.message.TempoMessage;
import com.musichord.core.track.DefaultTrack;
import com.musichord.core.track.MCTrack;

public class MCSequence {
	private Sequence sequence;
	private Track ctrlTrack;
	private List<MCTrack> tracks = new Vector<MCTrack>();

	public MCSequence(Sequence sequence) {
		this.sequence = sequence;
		this.ctrlTrack = this.sequence.createTrack();
	}

	public MCSequence() {
		try {
			this.sequence = new Sequence(Sequence.PPQ, 8);
		} catch (InvalidMidiDataException e) {
			e.printStackTrace();
		}
		this.ctrlTrack = this.sequence.createTrack();
	}

	public void setMeter(int x, int y, long tick) {
		ctrlTrack.add(new MidiEvent(new MeterMessage(x, y), tick));
	}

	public void setTempo(int tempo, long tick) {
		ctrlTrack.add(new MidiEvent(new TempoMessage(tempo), tick));
	}

	public void setInstrument(int inst, long tick) {
		ctrlTrack.add(new MidiEvent(new InstrumentMessage(inst), tick));
	}

	public MCTrack createTrack() {
		MCTrack result = new MCTrack(this.sequence.createTrack());
		this.tracks.add(result);
		return result;
	}

	public DefaultTrack createDefaultTrack() {
		DefaultTrack result = new DefaultTrack(this.sequence.createTrack());
		this.tracks.add(result);
		return result;
	}

	public void playSequence() throws MidiUnavailableException,
			InvalidMidiDataException, InterruptedException {
		Sequencer sequencer = MidiSystem.getSequencer(true);
		sequencer.setSequence(sequence);
		sequencer.open();
		sequencer.start();
		while (sequencer.isRunning()) {
			Thread.sleep(100);
		}
		sequencer.stop();
		sequencer.close();
	}

	public void Write2File(String filePath) {
		File file = new File(filePath);
		try {
			file.createNewFile();
			MidiSystem.write(sequence, 1, file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
